package com.digdes.calendar.dao.impl;

import com.digdes.calendar.dao.EventDAO;
import com.digdes.calendar.model.Event;
import com.digdes.calendar.model.impl.EventImpl;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class EventDAOImpl extends HibernateDaoSupport implements EventDAO {

    public void saveEvent(Event e) {
        getHibernateTemplate().save(e);
    }

    public void updateEvent(Event e) {
        getHibernateTemplate().update(e);
    }

    public void deleteEvent(Long id) {
       // getHibernateTemplate().delete(new EventImpl(id));
        getHibernateTemplate().delete(getHibernateTemplate().get(EventImpl.class, id));
    }

    public Event findEvent(Long id) {
        return (Event) getHibernateTemplate().get(EventImpl.class, id);

    }

    public Set<Event> getAllEvent() {
        return new HashSet<Event> (getHibernateTemplate().loadAll(EventImpl.class));
    }
    public Set<Event> getEventsByUserAndDate(Long userID, Date start, Date finish) {
        DetachedCriteria criteria = DetachedCriteria.forClass(EventImpl.class);
        criteria.add(Restrictions.eq("author.id", userID)).add(Restrictions.or
                (Restrictions.and(Restrictions.lt("dateStart",finish),Restrictions.ge("dateStart",start)),
                        Restrictions.or(Restrictions.and(Restrictions.le("dateFinish",finish),Restrictions.gt("dateFinish",start)),
                                Restrictions.and(Restrictions.le("dateStart", start), Restrictions.ge("dateFinish", finish)))));

        DetachedCriteria newcriteria = DetachedCriteria.forClass(EventImpl.class).add(Restrictions.or
                (Restrictions.and(Restrictions.lt("dateStart",finish),Restrictions.ge("dateStart",start)),
                        Restrictions.or(Restrictions.and(Restrictions.le("dateFinish",finish),Restrictions.gt("dateFinish",start)),
                                Restrictions.and(Restrictions.le("dateStart", start), Restrictions.ge("dateFinish", finish)))));
        newcriteria.createCriteria("participants").add(Restrictions.eq("participant.id", userID));


        HashSet<Event> set1 = new HashSet<Event>(getHibernateTemplate().findByCriteria(criteria));
        set1.addAll(new HashSet<Event>(getHibernateTemplate().findByCriteria(newcriteria)));
        return set1;
    }

    public Set<Event> getEventsByPlaceAndDate(Long placeID, Date start, Date finish) {
        DetachedCriteria criteria = DetachedCriteria.forClass(EventImpl.class);
        criteria.add(Restrictions.eq("place.id", placeID)).add(Restrictions.or
                (Restrictions.and(Restrictions.lt("dateStart",finish),Restrictions.ge("dateStart",start)),
                        Restrictions.or(Restrictions.and(Restrictions.le("dateFinish",finish),Restrictions.gt("dateFinish",start)),
                                Restrictions.and(Restrictions.le("dateStart", start), Restrictions.ge("dateFinish", finish)))));
        return new HashSet<Event>((getHibernateTemplate().findByCriteria(criteria)));
    }

    public List<Event> getEventsBetween(Date dStart, Date dFinish) {
        DetachedCriteria criteria = DetachedCriteria.forClass(EventImpl.class);
        criteria.add(Restrictions.or(Restrictions.between("dateStart", dStart, dFinish),
                Restrictions.between("dateFinish", dStart,
                        new Date(dFinish.getTime() + 24 * 3600 * 1000))));
        //criteria.addOrder(Order.asc("dateStart"));
        return getHibernateTemplate().findByCriteria(criteria);
    }

    public List<Event> getOldEvents(Date d) {
        DetachedCriteria criteria = DetachedCriteria.forClass(EventImpl.class);
        criteria.add(Restrictions.ge("dateStart", d));
        criteria.addOrder(Order.asc("dateStart"));
        return getHibernateTemplate().findByCriteria(criteria);
    }

    public List<Event> getEvents(Date d) {
        DetachedCriteria criteria = DetachedCriteria.forClass(EventImpl.class);
       // criteria.add(Restrictions.ge("dateStart", d));
        Date dF = new Date(d.getTime() + 24 * 3600 * 1000);
        criteria.add((Restrictions.ge("dateStart",d))).add(Restrictions.le("dateFinish", dF) );
        return getHibernateTemplate().findByCriteria(criteria);
    }
}
